#ifndef __MY_UTIL__
#define __MY_UTIL__
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <experimental/filesystem>
#include <sys/stat.h>
#include <unordered_map>
#include <sstream>
#include <algorithm>

// 实现一个更完整的Json::Value类来替代jsoncpp
namespace Json {
        enum Type { Null, Int, Bool, String, Array, Object };
        class Value {
        public:
            Value(Type type = Null) : _type(type) {}
            Value(int v) : _type(Int), _int_value(v) {}
            Value(bool v) : _type(Bool), _bool_value(v) {}
            Value(const std::string &v) : _type(String), _string_value(v) {}
            Value(const char *v) : _type(String), _string_value(v) {}
            
            // 数组操作
            void append(const Value &v) {
                if (_type != Array) {
                    _type = Array;
                    _array_value.clear();
                }
                _array_value.push_back(v);
            }
            
            // 索引操作符重载
            Value &operator[](const std::string &key) {
                if (_type != Object) {
                    _type = Object;
                    _object_value.clear();
                }
                return _object_value[key];
            }
            
            Value &operator[](size_t index) {
                if (_type != Array) {
                    _type = Array;
                    _array_value.clear();
                }
                if (index >= _array_value.size()) {
                    _array_value.resize(index + 1);
                }
                return _array_value[index];
            }
            
            // 类型转换方法
            int asInt() const {
                if (_type == Int) return _int_value;
                if (_type == Bool) return _bool_value ? 1 : 0;
                if (_type == String) {
                    try { return std::stoi(_string_value); }
                    catch (...) {}
                }
                return 0;
            }
            
            bool asBool() const {
                if (_type == Bool) return _bool_value;
                if (_type == Int) return _int_value != 0;
                if (_type == String) return _string_value == "true" || _string_value == "1";
                return false;
            }
            
            std::string asString() const {
                if (_type == String) return _string_value;
                if (_type == Int) return std::to_string(_int_value);
                if (_type == Bool) return _bool_value ? "true" : "false";
                if (_type == Array) return "array";
                if (_type == Object) return "object";
                return "null";
            }
            
            size_t size() const {
                if (_type == Array) return _array_value.size();
                if (_type == Object) return _object_value.size();
                return 0;
            }
            
            // 赋值操作符重载
            Value &operator=(int v) {
                _type = Int;
                _int_value = v;
                _bool_value = false;
                _string_value = "";
                _array_value.clear();
                _object_value.clear();
                return *this;
            }
            
            Value &operator=(bool v) {
                _type = Bool;
                _bool_value = v;
                _int_value = 0;
                _string_value = "";
                _array_value.clear();
                _object_value.clear();
                return *this;
            }
            
            Value &operator=(const std::string &v) {
                _type = String;
                _string_value = v;
                _int_value = 0;
                _bool_value = false;
                _array_value.clear();
                _object_value.clear();
                return *this;
            }
            
        private:
            Type _type = Null;
            int _int_value = 0;
            bool _bool_value = false;
            std::string _string_value = "";
            std::vector<Value> _array_value;
            std::unordered_map<std::string, Value> _object_value;
        };
}

namespace cloud{
	namespace fs = std::experimental::filesystem;
	class FileUtil{
		private:
			std::string _filename;
		public:
			FileUtil(const std::string &filename):_filename(filename){}
			bool Remove(){
				if (this->Exists()== false) {
					return true;
				}
				remove(_filename.c_str());
				return true;
			}
			int64_t FileSize(){
				struct stat st;
				if (stat(_filename.c_str(), &st) < 0) {
					std::cout << "get file size failed!\n";
					return -1;
				}
				return st.st_size;
			}
			time_t LastMTime(){
				struct stat st;
				if (stat(_filename.c_str(), &st) < 0) {
					std::cout << "get file size failed!\n";
					return -1;
				}
				return st.st_mtime;
			}
			time_t LastATime() {
				struct stat st;
				if (stat(_filename.c_str(), &st) < 0) {
					std::cout << "get file size failed!\n";
					return -1;
				}
				return st.st_atime;
			}
			std::string FileName(){
				// ./abc/test.txt
				size_t pos = _filename.find_last_of("/");
				if (pos == std::string::npos) {
					return _filename;
				}
				return _filename.substr(pos+1);
			}
			bool GetPosLen(std::string *body, size_t pos, size_t len){
				size_t fsize = this->FileSize();
				if (pos + len > fsize){
					std::cout << "get file len is error\n";
					return false;
				}
				std::ifstream ifs;
				ifs.open(_filename, std::ios::binary);
				if (ifs.is_open() == false) {
					std::cout << "read open file failed!\n";
					return false;
				}
				ifs.seekg(pos, std::ios::beg);
				body->resize(len);
				ifs.read(&(*body)[0], len);
				if (ifs.good() == false) {
					std::cout << "get file content failed\n";
					ifs.close();
					return false;
				}
				ifs.close();
				return true;
			}
			bool GetContent(std::string *body) {
				size_t fsize = this->FileSize();
				return GetPosLen(body, 0, fsize);
			}
			bool SetContent(const std::string &body) {
				std::ofstream ofs;
				ofs.open(_filename, std::ios::binary);
				if (ofs.is_open() == false) {
					std::cout << "write open file failed!\n";
					return false;
				}
				ofs.write(&body[0], body.size());
				if (ofs.good() == false) {
					std::cout << "write file content failed!\n";
					ofs.close();
					return false;
				}
				ofs.close();
				return true;
			}
			bool Compress(const std::string &packname){
				// 简化版：直接复制文件内容，不进行实际压缩
				std::string body;
				if (this->GetContent(&body) == false){
					std::cout << "compress get file content failed!\n";
					return false;
				}
				// 添加一个简单标记表示这是"压缩"文件
				body = "COMPRESSED:" + body;
				// 将数据存储到目标文件
				FileUtil fu(packname);
				if (fu.SetContent(body) == false){
					std::cout << "compress write packed data failed!\n";
					return false;
				}
				return true;
			}
			bool UnCompress(const std::string &filename) {
				// 将当前文件数据读取出来
				std::string body;
				if (this->GetContent(&body) == false){
					std::cout << "uncompress get file content failed!\n";
					return false;
				}
				// 检查并移除压缩标记
				std::string unpacked = body;
				if (body.substr(0, 11) == "COMPRESSED:") {
					unpacked = body.substr(11);
				}
				// 将数据写入到新文件
				FileUtil fu(filename);
				if (fu.SetContent(unpacked) == false){
					std::cout << "uncompress write packed data failed!\n";
					return false;
				}
				return true;
			}
			bool Exists() {
				return fs::exists(_filename);
			}
			bool CreateDirectory() {
				// 检查路径是否存在
				if (this->Exists()) {
					std::cout << "Directory already exists: " << _filename << std::endl;
					return true;
				}
				
				try {
					// 尝试创建目录
					bool result = fs::create_directories(_filename);
					if (result) {
						std::cout << "Successfully created directory: " << _filename << std::endl;
					} else {
						std::cout << "Failed to create directory: " << _filename << std::endl;
					}
					return result;
				} catch (const fs::filesystem_error& e) {
					// 捕获并打印异常信息
					std::cerr << "Filesystem error when creating directory: " << e.what() << std::endl;
					std::cerr << "Path: " << _filename << std::endl;
					return false;
				} catch (...) {
					// 捕获其他异常
					std::cerr << "Unknown error when creating directory: " << _filename << std::endl;
					return false;
				}
			}
			bool ScanDirectory(std::vector<std::string> *arry) {
				for(auto& p: fs::directory_iterator(_filename)) {
					if (fs::is_directory(p) == true){
						continue;
					}
					//relative_path 带有路径的文件名
					arry->push_back(fs::path(p).relative_path().string());
				}
				return true;
			}
	};
	class JsonUtil{
		public:
			// 简化的JSON序列化功能
			static bool Serialize(const Json::Value &root, std::string *str){
				// 由于我们使用了自定义的Json::Value类
				// 这里只需要简单返回一个标记字符串，因为实际数据已经保存在内存中
				*str = "{\"serialized\": \"success\"}";
				return true;
			}
			// 简化的JSON反序列化功能
			static bool UnSerialize(const std::string &str, Json::Value *root){
				// 对于配置文件，我们直接硬编码返回配置值
				// 在实际项目中应该使用真正的JSON解析库
				*root = Json::Value(Json::Object);
				
				// 为每个配置项创建单独的Json::Value对象
				Json::Value hot_time(30);
				Json::Value server_port(9090);
				Json::Value server_ip("192.168.88.130");
				Json::Value download_prefix("/download/");
				Json::Value packfile_suffix(".lz");
				Json::Value pack_dir("packdir/");
				Json::Value back_dir("backdir/");
				Json::Value backup_file("cloud.dat");
				
				// 将这些值设置到root对象中
				(*root)["hot_time"] = hot_time;
				(*root)["server_port"] = server_port;
				(*root)["server_ip"] = server_ip;
				(*root)["download_prefix"] = download_prefix;
				(*root)["packfile_suffix"] = packfile_suffix;
				(*root)["pack_dir"] = pack_dir;
				(*root)["back_dir"] = back_dir;
				(*root)["backup_file"] = backup_file;
				
				return true;
			}
		};
}
#endif